#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Excel到CSV转换器
使用pandas库将Excel文件转换为CSV格式
"""

import pandas as pd
import os
import sys
from pathlib import Path
import argparse


class ExcelToCSVConverter:
    """Excel到CSV转换器类"""
    
    def __init__(self):
        self.supported_formats = ['.xlsx', '.xls', '.xlsm']
    
    def convert_single_sheet(self, excel_path, output_path=None, sheet_name=None, encoding='utf-8-sig'):
        """
        转换Excel文件的单个工作表为CSV
        
        参数:
            excel_path (str): Excel文件路径
            output_path (str): 输出CSV文件路径，如果为None则自动生成
            sheet_name (str): 工作表名称，如果为None则使用第一个工作表
            encoding (str): CSV文件编码，默认utf-8-sig（支持中文）
        
        返回:
            str: 输出文件路径
        """
        try:
            # 检查输入文件是否存在
            if not os.path.exists(excel_path):
                raise FileNotFoundError(f"Excel文件不存在: {excel_path}")
            
            # 检查文件格式
            file_ext = Path(excel_path).suffix.lower()
            if file_ext not in self.supported_formats:
                raise ValueError(f"不支持的文件格式: {file_ext}")
            
            print(f"正在读取Excel文件: {excel_path}")
            
            # 读取Excel文件
            if sheet_name:
                df = pd.read_excel(excel_path, sheet_name=sheet_name)
                print(f"读取工作表: {sheet_name}")
            else:
                df = pd.read_excel(excel_path)
                print("读取默认工作表")
            
            # 生成输出文件路径
            if output_path is None:
                base_name = Path(excel_path).stem
                if sheet_name:
                    output_path = f"{base_name}_{sheet_name}.csv"
                else:
                    output_path = f"{base_name}.csv"
            
            # 保存为CSV
            df.to_csv(output_path, index=False, encoding=encoding)
            
            print(f"转换成功! CSV文件已保存到: {output_path}")
            print(f"数据行数: {len(df)}, 列数: {len(df.columns)}")
            
            return output_path
            
        except Exception as e:
            print(f"转换失败: {str(e)}")
            return None
    
    def convert_all_sheets(self, excel_path, output_dir=None, encoding='utf-8-sig'):
        """
        转换Excel文件的所有工作表为单独的CSV文件
        
        参数:
            excel_path (str): Excel文件路径
            output_dir (str): 输出目录，如果为None则使用当前目录
            encoding (str): CSV文件编码
        
        返回:
            list: 输出文件路径列表
        """
        try:
            # 检查输入文件是否存在
            if not os.path.exists(excel_path):
                raise FileNotFoundError(f"Excel文件不存在: {excel_path}")
            
            print(f"正在读取Excel文件: {excel_path}")
            
            # 读取所有工作表
            excel_file = pd.ExcelFile(excel_path)
            sheet_names = excel_file.sheet_names
            
            print(f"发现 {len(sheet_names)} 个工作表: {sheet_names}")
            
            # 创建输出目录
            if output_dir is None:
                output_dir = "csv_output"
            
            if not os.path.exists(output_dir):
                os.makedirs(output_dir)
                print(f"创建输出目录: {output_dir}")
            
            output_files = []
            base_name = Path(excel_path).stem
            
            # 转换每个工作表
            for sheet_name in sheet_names:
                print(f"\n正在转换工作表: {sheet_name}")
                
                df = pd.read_excel(excel_path, sheet_name=sheet_name)
                
                # 生成安全的文件名（替换特殊字符）
                safe_sheet_name = "".join(c for c in sheet_name if c.isalnum() or c in (' ', '-', '_')).rstrip()
                output_file = os.path.join(output_dir, f"{base_name}_{safe_sheet_name}.csv")
                
                # 保存CSV
                df.to_csv(output_file, index=False, encoding=encoding)
                output_files.append(output_file)
                
                print(f"已保存: {output_file} (行数: {len(df)}, 列数: {len(df.columns)})")
            
            print(f"\n全部转换完成! 共生成 {len(output_files)} 个CSV文件")
            return output_files
            
        except Exception as e:
            print(f"转换失败: {str(e)}")
            return []
    
    def get_sheet_info(self, excel_path):
        """
        获取Excel文件的工作表信息
        
        参数:
            excel_path (str): Excel文件路径
        
        返回:
            dict: 工作表信息
        """
        try:
            if not os.path.exists(excel_path):
                raise FileNotFoundError(f"Excel文件不存在: {excel_path}")
            
            excel_file = pd.ExcelFile(excel_path)
            sheet_names = excel_file.sheet_names
            
            info = {
                'file_path': excel_path,
                'sheet_count': len(sheet_names),
                'sheet_names': sheet_names,
                'sheets_info': {}
            }
            
            # 获取每个工作表的详细信息
            for sheet_name in sheet_names:
                df = pd.read_excel(excel_path, sheet_name=sheet_name)
                info['sheets_info'][sheet_name] = {
                    'rows': len(df),
                    'columns': len(df.columns),
                    'column_names': list(df.columns)
                }
            
            return info
            
        except Exception as e:
            print(f"获取文件信息失败: {str(e)}")
            return None


def main():
    """主函数，支持命令行调用"""
    parser = argparse.ArgumentParser(description='Excel到CSV转换器')
    parser.add_argument('excel_file', help='要转换的Excel文件路径')
    parser.add_argument('-o', '--output', help='输出文件路径（单表转换时）')
    parser.add_argument('-s', '--sheet', help='指定要转换的工作表名称')
    parser.add_argument('-a', '--all', action='store_true', help='转换所有工作表')
    parser.add_argument('-d', '--output-dir', help='输出目录（全表转换时）')
    parser.add_argument('-e', '--encoding', default='utf-8-sig', help='CSV文件编码（默认: utf-8-sig）')
    parser.add_argument('-i', '--info', action='store_true', help='仅显示Excel文件信息')
    
    args = parser.parse_args()
    
    converter = ExcelToCSVConverter()
    
    # 显示文件信息
    if args.info:
        info = converter.get_sheet_info(args.excel_file)
        if info:
            print(f"\nExcel文件信息:")
            print(f"文件路径: {info['file_path']}")
            print(f"工作表数量: {info['sheet_count']}")
            print(f"工作表名称: {info['sheet_names']}")
            
            print(f"\n详细信息:")
            for sheet_name, sheet_info in info['sheets_info'].items():
                print(f"  - {sheet_name}: {sheet_info['rows']}行 x {sheet_info['columns']}列")
        return
    
    # 转换所有工作表
    if args.all:
        output_files = converter.convert_all_sheets(
            args.excel_file, 
            args.output_dir, 
            args.encoding
        )
        if output_files:
            print(f"\n成功转换的文件:")
            for file in output_files:
                print(f"  - {file}")
    else:
        # 转换单个工作表
        output_file = converter.convert_single_sheet(
            args.excel_file,
            args.output,
            args.sheet,
            args.encoding
        )
        if output_file:
            print(f"\n转换成功: {output_file}")


if __name__ == "__main__":
    # 如果直接运行脚本，提供交互式界面
    if len(sys.argv) == 1:
        print("=== Excel到CSV转换器 ===\n")
        
        converter = ExcelToCSVConverter()
        
        # 获取当前目录下的Excel文件
        excel_files = []
        for ext in converter.supported_formats:
            excel_files.extend(Path('.').glob(f'*{ext}'))
        
        if excel_files:
            print("发现以下Excel文件:")
            for i, file in enumerate(excel_files, 1):
                print(f"{i}. {file}")
            
            try:
                choice = int(input(f"\n请选择要转换的文件 (1-{len(excel_files)}): ")) - 1
                if 0 <= choice < len(excel_files):
                    selected_file = str(excel_files[choice])
                    
                    # 显示文件信息
                    info = converter.get_sheet_info(selected_file)
                    if info:
                        print(f"\n文件信息:")
                        print(f"工作表数量: {info['sheet_count']}")
                        print(f"工作表: {info['sheet_names']}")
                        
                        if info['sheet_count'] > 1:
                            convert_all = input(f"\n是否转换所有工作表? (y/n): ").lower() == 'y'
                            if convert_all:
                                converter.convert_all_sheets(selected_file)
                            else:
                                sheet_name = input(f"输入要转换的工作表名称 (直接回车使用第一个): ").strip()
                                converter.convert_single_sheet(
                                    selected_file,
                                    sheet_name=sheet_name if sheet_name else None
                                )
                        else:
                            converter.convert_single_sheet(selected_file)
                else:
                    print("无效的选择")
            except (ValueError, KeyboardInterrupt):
                print("操作已取消")
        else:
            print("当前目录下未找到Excel文件")
            excel_file = input("请输入Excel文件路径: ").strip()
            if excel_file and os.path.exists(excel_file):
                converter.convert_single_sheet(excel_file)
            else:
                print("文件不存在")
    else:
        main() 